import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import quick.dbtable.*;
import java.awt.event.WindowEvent;

/**
 * A JFrame for holding the components of the application.
 *
 * @author Jacel Evasco
 * @author Roselle Nympha Lim
 * @version 1.0
 */
public class Explorer extends JFrame {

    private static final Explorer EXPLORER = new Explorer();
    public String profileID;
    private JPanel tabs = new JPanel();
    private JLabel tabsBG = new JLabel(new ImageIcon(
        "images\\backgrounds\\mainTabsBG.png"));
    private JPanel cards = new JPanel();
    private JLabel cardsBG = new JLabel(new ImageIcon(
        "images\\backgrounds\\mainCardsBG.png"));
    private JButton requirement = new JButton(new ImageIcon(
        "images\\icons\\requirementNormal.png"));
    private JButton goal = new JButton(new ImageIcon(
        "images\\icons\\goalNormal.png"));
    private JButton user = new JButton(new ImageIcon(
        "images\\icons\\userNormal.png"));
    private JButton subject = new JButton(new ImageIcon(
        "images\\icons\\subjectNormal.png"));
    private JLabel iD = new JLabel(profileID);
    private RequirementsViewer requirementsViewer = new RequirementsViewer();
    private GoalsViewer goalsViewer = new GoalsViewer();
    private SubjectsChooser subjectsChooser = new SubjectsChooser();
    private ProfileMenu profileMenu = new ProfileMenu();

    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;

    private Explorer() {
        assemble();
        configure();
        design();
        setTriggers();
        display();
    } // end of Explorer()

    private void prepareConnection() {
        try {
            connection = DatabaseUtility.prepareConnection();
        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch
    } // end of setID method

    private void assemble() {
        // tabs
        tabs.setLayout(new BoxLayout(tabs, BoxLayout.Y_AXIS));
        tabs.add(Box.createRigidArea(new Dimension(0, 16)));
        tabs.add(subject);
        tabs.add(Box.createRigidArea(new Dimension(0, 16)));
        tabs.add(requirement);
        tabs.add(Box.createRigidArea(new Dimension(0, 16)));
        tabs.add(goal);
        tabs.add(Box.createRigidArea(new Dimension(0, 367)));
        tabs.add(user);
        tabs.add(Box.createRigidArea(new Dimension(0, 1)));
        tabs.add(iD);
        // cards
        cards.setLayout(new CardLayout());
        cards.add(requirementsViewer, "requirementsViewer");
        cards.add(goalsViewer, "goalsViewer");
        // tabsBG
        tabsBG.setLayout(new BorderLayout());
        tabsBG.add(tabs);
        // cardsBG
        cardsBG.setLayout(new BorderLayout());
        cardsBG.add(cards);
        // content pane
        getContentPane().setLayout(
            new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
        getContentPane().add(tabsBG);
        getContentPane().add(cardsBG);
    } // end of assemble()

    private void configure() {
        fetchID();
    } // end of configure()

    private void design() {
        // sizes
        requirement.setPreferredSize(new Dimension(46, 32));
        requirement.setMinimumSize(new Dimension(46, 32));
        requirement.setMaximumSize(new Dimension(46, 32));
        goal.setPreferredSize(new Dimension(46, 32));
        goal.setMinimumSize(new Dimension(46, 32));
        goal.setMaximumSize(new Dimension(46, 32));
        user.setPreferredSize(new Dimension(46, 32));
        user.setMinimumSize(new Dimension(46, 32));
        user.setMaximumSize(new Dimension(46, 32));
        subject.setPreferredSize(new Dimension(46, 32));
        subject.setMinimumSize(new Dimension(46, 32));
        subject.setMaximumSize(new Dimension(46, 32));
        iD.setPreferredSize(new Dimension(46, 12));
        iD.setMinimumSize(new Dimension(46, 12));
        iD.setMaximumSize(new Dimension(46, 12));
        tabsBG.setPreferredSize(new Dimension(46, 600));
        tabsBG.setMinimumSize(new Dimension(46, 600));
        tabsBG.setMaximumSize(new Dimension(46, 600));
        cardsBG.setPreferredSize(new Dimension(954, 600));
        cardsBG.setMinimumSize(new Dimension(954, 600));
        cardsBG.setMaximumSize(new Dimension(954, 600));
        // backgrounds
        tabs.setOpaque(false);
        cards.setOpaque(false);
        requirementsViewer.setOpaque(false);
        goalsViewer.setOpaque(false);
        // font styles
        iD.setFont(new Font("Segoe UI", Font.PLAIN, 11));
        // font colors
        iD.setForeground(new Color(204, 204, 204));
        // alignments
        iD.setHorizontalAlignment(JLabel.CENTER);
        // button styles
        requirement.setOpaque(false);
        requirement.setContentAreaFilled(false);
        requirement.setBorderPainted(false);
        goal.setOpaque(false);
        goal.setContentAreaFilled(false);
        goal.setBorderPainted(false);
        user.setOpaque(false);
        user.setContentAreaFilled(false);
        user.setBorderPainted(false);
        subject.setOpaque(false);
        subject.setContentAreaFilled(false);
        subject.setBorderPainted(false);
    } // end of design()

    private void setTriggers() {
        MouseListener mouseTrigger = new MouseListener() {
            public void mouseClicked(MouseEvent me) {
                if (me.getSource() == requirement) {
                    try {
                        getRequirementsViewer().getData().refresh();
                    } catch (Exception noise) {
                    }
                    getGoalsViewer().isDataEmpty();
                    getRequirementsViewer().isDataEmpty();
                    ((CardLayout) cards.getLayout()).show(cards,
                        "requirementsViewer");
                    setTitle("Student Requirements Tracker > "
                        + profileID + " > Requirements");
                } else if (me.getSource() == goal) {
                    try {
                        getGoalsViewer().getData().refresh();
                    } catch (Exception noise) {
                    }
                    getGoalsViewer().isDataEmpty();
                    getRequirementsViewer().isDataEmpty();
                    ((CardLayout) cards.getLayout()).show(cards,
                        "goalsViewer");
                    setTitle("Student Requirements Tracker > "
                        + profileID + " > Goals");
                } else if (me.getSource() == user) {
                    profileMenu.setVisible(true);
                } else if (me.getSource() == subject) {
                    try {
                        subjectsChooser.fetchCourses();
                        subjectsChooser.fetchSemesters();
                        subjectsChooser.fetchYears();
                        subjectsChooser.getData().refresh();
                        subjectsChooser.getUserData().refresh();
                    } catch (Exception noise) {
                        noise.printStackTrace();
                    }
                    subjectsChooser.setVisible(true);
                }
            } // end of mouseClicked()

            public void mouseEntered(MouseEvent me) {
                if (me.getSource() == requirement) {
                    requirement.setIcon(new ImageIcon(
                        "images\\icons\\requirementEntered.png"));
                } else if (me.getSource() == goal) {
                    goal.setIcon(new ImageIcon(
                        "images\\icons\\goalEntered.png"));
                } else if (me.getSource() == user) {
                    user.setIcon(new ImageIcon(
                        "images\\icons\\userEntered.png"));
                } else if (me.getSource() == subject) {
                    subject.setIcon(new ImageIcon(
                        "images\\icons\\subjectEntered.png"));
                }
            } // end of mouseEntered()

            public void mouseExited(MouseEvent me) {
                if (me.getSource() == requirement) {
                    requirement.setIcon(new ImageIcon(
                        "images\\icons\\requirementNormal.png"));
                } else if (me.getSource() == goal) {
                    goal.setIcon(new ImageIcon(
                        "images\\icons\\goalNormal.png"));
                } else if (me.getSource() == user) {
                    user.setIcon(new ImageIcon(
                        "images\\icons\\userNormal.png"));
                } else if (me.getSource() == subject) {
                    subject.setIcon(new ImageIcon(
                        "images\\icons\\subjectNormal.png"));
                }
            } // end of mouseExited()

            public void mousePressed(MouseEvent me) {
                if (me.getSource() == requirement) {
                    requirement.setIcon(new ImageIcon(
                        "images\\icons\\requirementPressed.png"));
                } else if (me.getSource() == goal) {
                    goal.setIcon(new ImageIcon(
                        "images\\icons\\goalPressed.png"));
                } else if (me.getSource() == user) {
                    user.setIcon(new ImageIcon(
                        "images\\icons\\userPressed.png"));
                } else if (me.getSource() == subject) {
                    subject.setIcon(new ImageIcon(
                        "images\\icons\\subjectPressed.png"));
                }
            } // end of mousePressed()

            public void mouseReleased(MouseEvent me) {
                if (me.getSource() == requirement) {
                    requirement.setIcon(new ImageIcon(
                        "images\\icons\\requirementNormal.png"));
                } else if (me.getSource() == goal) {
                    goal.setIcon(new ImageIcon(
                        "images\\icons\\goalNormal.png"));
                } else if (me.getSource() == user) {
                    user.setIcon(new ImageIcon(
                        "images\\icons\\userNormal.png"));
                } else if (me.getSource() == subject) {
                    subject.setIcon(new ImageIcon(
                        "images\\icons\\subjectNormal.png"));
                }
            } // end of mouseReleased()
        }; // end of mouseTrigger

        requirement.addMouseListener(mouseTrigger);
        goal.addMouseListener(mouseTrigger);
        user.addMouseListener(mouseTrigger);
        subject.addMouseListener(mouseTrigger);

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent windowEvent) {
                prepareConnection();

                String updateStatus = "UPDATE requirementstrackerschema.student"
                    + " SET isLoggedIn = '0' WHERE isLoggedIn = '1'";

                try {
                    preparedStatement = connection
                        .prepareStatement(updateStatus);
                    preparedStatement.executeUpdate();

                    getInstance().fetchID();
                    getInstance().getProfileMenu().getProfilePeeker()
                        .fetchID();
                    getInstance().getProfileMenu().getProfileEditor()
                        .cleanUp();
                    getInstance().getProfileMenu().getProfileEditor()
                        .fetchID();
                    getInstance().getProfileMenu()
                        .getProfileAuthenticator().cleanUp();
                    getInstance().getProfileMenu().getProfileMaker()
                        .cleanUp();

                } catch (Exception e) {
                    e.printStackTrace();
                } // end of try-catch

                System.exit(0);
            }
        });

    } // end of setTriggers()

    private void display() {

        setTitle("Student Requirements Tracker");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000, 600);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    } // end of display()

    public RequirementsViewer getRequirementsViewer() {
        return requirementsViewer;
    } // end of getRequirementsViewer()

    public GoalsViewer getGoalsViewer() {
        return goalsViewer;
    } // end of getGoalsViewer()

    public ProfileMenu getProfileMenu() {
        return profileMenu;
    } // end of getProfileMenu()

    public static Explorer getInstance() {
        return EXPLORER;
    } // end of getInstance()

    public void fetchID() {
        prepareConnection();
        String query = "SELECT * FROM requirementstrackerschema.student"
            + " WHERE isLoggedIn = 1";
        try {
            preparedStatement = connection.prepareStatement(query);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                profileID = resultSet.getString("studentID");
                iD.setText(profileID);
            } else {
                iD.setText("");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } // end of try-catch
    } // end of fetchID()

    public static void main(String[] args) {

        Explorer explorer = Explorer.getInstance();
        Explorer.getInstance().getProfileMenu().setVisible(true);
    } // end of main(String[] args)
} // end of Explorer